﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kugar.Core.Exceptions;
using Kugar.Core.ExtMethod;
using Kugar.Core.Security;
using Kugar.ERPFramework.BLLInterface;
using Kugar.ERPFramework.Core.Entity;
using Kugar.ERPFramework.Core.Interfaces;
using Kugar.ERPFramework.Core.Interfaces.BLL;

namespace Kugar.ERPFramework.ClientBroker
{


    public interface IClientBroker
    {
        #region 属性

        Uri ServerIP { set; get; }

        #endregion

        #region 函数

        #region 用户相关

        LoginUserInfo LoginUser(string userName, string password);
        bool LogoutUser();

        LoginUserInfo CurrentUser { get; }

        #endregion

        #region 权限相关

        IUserPermissionChecker[] GetCurrentUserRMS();
        

        #endregion

        #region 数据相关
        void ViewData(string orderID);
        void ViewData(EntityBase entity);
        void ViewModule(string moduleFormName, params object[] args);

        EntityBase[] ShowDataFetcher(string dataFetcherName,bool enableMutliSelect=false, Dictionary<string, object> initValue=null);

        ICustomBLLModule GetControler(string controlerName);
        IModuleForm GetModuleForm(string moduleFormName, params object[] args);
        IDataFetcherForm GetDataFetcher(string dataFetcherName);
        EntityBase GetEntityByID(string mainID);
        string GetEntityFormName(Type entityType);

        void RegistrControler(ICustomBLLModule controler);
        void RegistrForm(string name, Type frmType);
        void RegistrDataFetcher(string name, Type fetcherType);
        void RegistrEntityTypeForm(Type entityType, string formName);
        void RegistrPrefixID(string prefix,IOpenable  controler);
        #endregion


        void ShowMessage(string msg, string caption = "");
        bool ShowMessageWithButton(string msg, string caption = "");
        string ShowInputBox(string caption, string msg);
        #endregion



        event EventHandler<ViewDataEventArgs> ViewDataRequest;
        event EventHandler<ViewModuleEventArgs> ViewModuleFormRequest;
        event EventHandler<ShowMessageEventArgs> ShowMessageRequest;
        event EventHandler<ShowDataFectherEventArgs> ShowDataFectherRequest;
    }


    public abstract class ClientBrokerBase : IClientBroker
    {
        protected Dictionary<string, Type> _cacheModuleForm = null;
        protected Dictionary<string, Type> _cacheFetcherForm = null;
        protected Dictionary<string, ICustomBLLModule> _cacheControler = null;
        protected Dictionary<Type, string> _cacheEntityType = null;
        protected Dictionary<string, IOrder> _cachePrefixControler = null;


        protected ClientBrokerBase()
        {
            _cacheModuleForm = new Dictionary<string, Type>();
            _cacheControler = new Dictionary<string, IDataModuleControler>();
            _cacheEntityType = new Dictionary<Type, string>();
            _cacheFetcherForm = new Dictionary<string, Type>();
            _cachePrefixControler=new Dictionary<string, IOrder>();
        }

        #region 接口属性
        public Uri ServerIP { get; set; }
        public LoginUserInfo LoginUser(string userName, string password)
        {
            throw new NotImplementedException();
        }

        public bool LogoutUser()
        {
            throw new NotImplementedException();
        }

        public LoginUserInfo CurrentUser { get; private set; }

        #endregion

        #region 接口函数

        public RMS_PermissionItemValue[] GetCurrentUserRMS()
        {
            throw new NotImplementedException();
        }

        public virtual void ViewData(string orderID)
        {
            var entity = GetEntityByID(orderID);

            if (entity == null)
            {
                throw new KeyNotFoundException("不存在指定ID的实体");
            }

            ViewData(entity);
        }

        public virtual void ViewData(EntityBase entity)
        {
            if (ViewDataRequest != null)
            {
                ViewDataRequest(this, new ViewDataEventArgs(entity));
            }
        }

        public virtual void ViewModule(string moduleFormName, params object[] args)
        {
            if (!_cacheModuleForm.ContainsKey(moduleFormName))
            {
                throw new ArgumentOutOfRangeException("moduleFormName", "不存在指定模块名的窗体");
            }

            if (ViewModuleFormRequest != null)
            {
                var e = new ViewModuleEventArgs(moduleFormName, args);

                ViewModuleFormRequest(this, e);
            }
        }


        public virtual EntityBase[] ShowDataFetcher(string dataFetcherName, bool enableMultiSelect = false, Dictionary<string, object> initValue = null)
        {
            if (ShowDataFectherRequest != null)
            {
                var e = new ShowDataFectherEventArgs(dataFetcherName, enableMultiSelect, initValue);

                ShowDataFectherRequest(this, e);

                return e.SelectItems;
            }
            else
            {
                return null;
            }
        }

        public virtual IDataModuleControler GetControler(string controlerName)
        {
            var controler = _cacheControler.TryGetValue(controlerName, null);

            if (controler == null)
            {
                throw new ArgumentOutOfRangeException("controlerName");
            }

            return controler;
        }

        public virtual IModuleForm GetModuleForm(string moduleFormName, params object[] args)
        {
            var frmType = _cacheModuleForm.TryGetValue(moduleFormName, null);

            if (frmType == null)
            {
                throw new ArgumentOutOfRangeException("moduleFormName");
            }

            return (IModuleForm)Activator.CreateInstance(frmType, args);

        }

        public virtual IDataFetcherForm GetDataFetcher(string dataFetcherName)
        {
            var frmType = _cacheFetcherForm.TryGetValue(dataFetcherName, null);

            if (frmType == null)
            {
                throw new ArgumentOutOfRangeException("dataFetcherName");
            }

            return (IDataFetcherForm)Activator.CreateInstance(frmType);

        }

        public virtual IOrder GetPrefixControler(string prefix)
        {
            if (!_cachePrefixControler.ContainsKey(prefix))
            {
                throw new ArgumentOutOfRangeException("mainID", "不存在指定前缀的处理程序");
            }

            var controler = _cachePrefixControler.TryGetValue(prefix);

            return controler;
        }

        public virtual EntityBase GetEntityByID(string mainID)
        {
            var index = mainID.IndexOf('-');
            EntityBase entity = null;

            if (index > 0)
            {
                var prefix = mainID.Substring(0, index);

                var controler = GetPrefixControler(prefix);

                if (controler != null)
                {
                    try
                    {
                        entity = controler.GetEntityByID(mainID);
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            if (entity == null)
            {
                entity = OnGetEntityByID(mainID);
            }

            return entity;

        }

        public virtual string GetEntityFormName(Type entityType)
        {
            return _cacheEntityType.TryGetValue(entityType);
        }

        public virtual void RegistrControler(IDataModuleControler controler)
        {
            if (_cacheControler.ContainsKey(controler.Name))
            {
                throw new ArgumentOutOfRangeException("controler");
            }

            _cacheControler.Add(controler.Name, controler);
        }

        public virtual void RegistrForm(string name, Type frmType)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentOutOfRangeException("name");
            }

            if (frmType == null)
            {
                throw new ArgumentNullException("frmType");
            }


            if (_cacheControler.ContainsKey(name))
            {
                throw new ArgumentOutOfRangeException("name");
            }

            if (!frmType.IsImplementlInterface(typeof(IModuleForm)))
            {
                throw new ArgumentTypeNotMatchException("frmType", "IModuleForm");
            }

            _cacheModuleForm.Add(name, frmType);
        }

        public virtual void RegistrDataFetcher(string name, Type fetcherType)
        {

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentOutOfRangeException("name");
            }

            if (fetcherType == null)
            {
                throw new ArgumentNullException("fetcherType");
            }

            if (_cacheControler.ContainsKey(name))
            {
                throw new ArgumentOutOfRangeException("name");
            }

            if (!fetcherType.IsImplementlInterface(typeof(IDataFetcherForm)))
            {
                throw new ArgumentTypeNotMatchException("fetcherType", "IDataFetcherForm");
            }

            _cacheFetcherForm.Add(name, fetcherType);
        }

        public void RegistrEntityTypeForm(Type entityType, string formName)
        {
            if (entityType == null)
            {
                throw new ArgumentNullException("entityType");
            }

            if (string.IsNullOrWhiteSpace(formName))
            {
                throw new ArgumentNullException("formName");
            }

            if (!_cacheModuleForm.ContainsKey(formName))
            {
                throw new ArgumentOutOfRangeException("formName", "请先调用注册函数注册窗体");
            }

            if (_cacheEntityType.ContainsKey(entityType))
            {
                throw new ArgumentOutOfRangeException("entityType", "该类型已注册过");
            }

            if (!entityType.IsAssignableFrom(typeof(EntityBase)))
            {
                throw new ArgumentTypeNotMatchException("entityType", "EntityBase");
            }

            _cacheEntityType.Add(entityType, formName);
        }

        public void RegistrPrefixID(string prefix, IOrder controler)
        {
            if (string.IsNullOrWhiteSpace(prefix))
            {
                throw new ArgumentNullException("prefix");
            }

            if (controler == null)
            {
                throw new ArgumentNullException("controler");
            }

            if (_cachePrefixControler.ContainsKey(prefix))
            {
                throw new ArgumentOutOfRangeException("prefix");
            }

            _cachePrefixControler.Add(prefix, controler);
        }


        public virtual void ShowMessage(string msg, string caption = "")
        {
            if (ShowMessageRequest != null)
            {
                ShowMessageRequest(this, new ShowMessageEventArgs(caption, msg));
            }
        }

        public virtual bool ShowMessageWithButton(string msg, string caption = "")
        {
            if (ShowMessageRequest != null)
            {
                var e = new ShowMessageEventArgs(caption, msg);

                ShowMessageRequest(this, e);

                return e.ReturnResult;
            }
            else
            {
                return false;
            }
        }

        public virtual string ShowInputBox(string caption, string msg)
        {
            if (ShowMessageRequest == null)
            {
                return string.Empty;
            }

            return string.Empty;
        }
        #endregion





        public event EventHandler<ViewDataEventArgs> ViewDataRequest;
        public event EventHandler<ViewModuleEventArgs> ViewModuleFormRequest;
        public event EventHandler<ShowMessageEventArgs> ShowMessageRequest;
        public event EventHandler<ShowDataFectherEventArgs> ShowDataFectherRequest;
        public event EventHandler<GetEntityByIDEventArgs> GetEntityByIDRequest;

        protected virtual EntityBase OnGetEntityByID(string mainID)
        {
            if (GetEntityByIDRequest!=null)
            {
                var e = new GetEntityByIDEventArgs(mainID);

                GetEntityByIDRequest(this, e);

                return e.Entity;
            }
            else
            {
                return null;
            }
        }
    }

    public class ViewDataEventArgs:EventArgs
    {
        public ViewDataEventArgs(EntityBase entity)
        {
            Entity = entity;
        }

        public EntityBase Entity { get; private set; }
    }

    public class ViewModuleEventArgs:EventArgs
    {
        public ViewModuleEventArgs(string moduleFormName,object[] args=null)
        {
            ModuleFormName = moduleFormName;
            Args = args;
        }

        public object[] Args { get; private set; }
        public string ModuleFormName { get; private set; }
    }

    public class ShowMessageEventArgs : EventArgs
    {
        public ShowMessageEventArgs(string caption, string text)
        {
            Caption = caption;
            Text = text;
        }

        public string Caption { set; get; }
        public string Text { set; get; }
        public bool HasButton { set; get; }
        public bool ReturnResult { set; get; }
    }


    public class ShowDataFectherEventArgs:EventArgs
    {
        public ShowDataFectherEventArgs(string fetcherName, bool enableMultiSelect=false, Dictionary<string, object> intiValue = null)
        {
            FetcherName = fetcherName;
            InitValue = intiValue;
        }

        public string FetcherName { get; protected set; }
        public Dictionary<string, object> InitValue { get; private set; }
        public bool EnableMultiSelect { set; get; }

        public EntityBase[] SelectItems { set; get; }
    }

    public class GetEntityByIDEventArgs:EventArgs
    {
        public GetEntityByIDEventArgs(string mainId)
        {
            MainID = mainId;
        }

        public string MainID {protected set; get; }
        public EntityBase Entity { set; get; }
    }

    public interface IModuleForm{}

    public interface IDataFetcherForm
    {
        EntityBase[] SelectItems { get; }

        bool Show(Dictionary<string, object> initValue);
    }


}
